/*
 *  Copyright (C) 2025 ameise <ameise.wang@gmail.com> - All Rights Reserved
 *
 *  This file is part of e3utils.
 *
 *  e3utils is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  e3utils is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with e3utils. If not, see <https://www.gnu.org/licenses/>.
 */

package sys

import (
	"context"
	"errors"
	"fmt"
	"net/http"
	_ "net/http/pprof"
	"os"
	"path/filepath"
	"runtime/pprof"

	"gitee.com/ameise84/e3utils/internal"
)

func DebugHttpPporf(port uint16, exit <-chan struct{}) {
	go func() {
		srv := http.Server{
			Addr: fmt.Sprintf(":%d", port),
		}
		go func() {
			if err := srv.ListenAndServe(); !errors.Is(err, http.ErrServerClosed) {
				internal.GetLogger().Error("pprof http start").Err(err).Println()
			}
		}()
		_ = <-exit
		if err := srv.Shutdown(context.Background()); err != nil {
			internal.GetLogger().Error("pprof http stop").Err(err).Println()
		}
	}()
}

func DebugFilePporf(path string, exit <-chan struct{}) {
	go func() {
		err := os.MkdirAll(path, 0666)
		if err != nil {
			internal.GetLogger().Error("make dir").Err(err).Println()
			return
		}
		fc, err := os.Create(filepath.Join(path, "cpu.prof"))
		if err != nil {
			internal.GetLogger().Error("pprof create cpu.prof").Err(err).Println()
			return
		}
		fm, err := os.Create(filepath.Join(path, "memory.prof"))
		if err != nil {
			internal.GetLogger().Error("pprof create memory.prof").Err(err).Println()
			return
		}
		err = pprof.StartCPUProfile(fc)
		if err != nil {
			internal.GetLogger().Error("pprof start cpu file").Err(err).Println()
			return
		}
		_ = <-exit
		err = pprof.WriteHeapProfile(fm)
		if err != nil {
			internal.GetLogger().Error("pprof write memory file").Err(err).Println()
			return
		}
		pprof.StopCPUProfile()
	}()
}
